home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Programming Sound Cards
/
Programming Sound Cards.iso
/
sound_52
/
ex1.ma
< prev
next >
Wrap
Text File
|
1995-01-01
|
7KB
|
387 lines
#
#
# Illustrates idea of using continuous controllers to
# implement pan between speakers
#
# four vcos used.
#
# 2 for melody
# 2 for pan control
#
# true setup
#
# vco melody on channel n
# vco melody dupped on channel n+1
#
# vco pan control 1
# volume messages to channel n
#
# vco pan control 2
# volume messages to channel n+1
#
# mos setup should map vco 4 to vco 2
# vco 3 to vco 1
#
# Mixer should have one vco to the left, one to the right.
# Set pan to hard left and hard right appropriately.
# Basic idea is that volume is continuously balanced by
# ccont messages on left and right; i.e., strong on left
# weak on right then move gradually to weak on left
# strong on right; apparent voice position will shift.
#
# This takes an input argument from mos
# e.g.,
#
# mos> set argv 3
#
PORTAMENTO = 5
VOLUME = 7
PAN = 10
SUSTAINPEDAL = 0x40
PANLEFT = 127
PANRIGHT = 30
TRUE = 1
FALSE = 0
# pan control variables, one per channel
#
int vol1
int vol2
# debug on/off
int debug=TRUE
# minor scale offsets, jazz minor
#
uchar minor[7]={
0,2,3,5,7,9,10
}
# major scale offsets, jazz major
#
uchar major[7]={
0,2,4,5,7,9,11
}
# chord progression
#
uchar basis[9]={
E,LE,E,G,LG,B,LB,D,LD
}
uchar notesPerRiff[9]={
6,12,6,12,12,6,3,9,12
}
uchar riffsPerBasis[10]={
2,4,6,6,8,6,4,4,2,4
}
int tottime
int panvalue
int octave=0
riff settime(beats,beatnote)
tottime = beats * beatnote
end
riff nexttime()
end
riff atoi(vector string)
int i
int n
for( i = 0; ; )
if ( string[i] == ' ')
i++
else
break
end
end
for ( n = 0; string[i] >= '0' && string[i] <= '9'; i++)
n = 10 * n + string[i] - '0'
end
return(n)
end
# move from current chord to next chord in progression
#
riff nextBasis(cur)
if ( cur == 9 )
return(0)
end
cur++
return(cur)
end
# determine how many notes for this riff
#
riff nextNotes(cur)
return(notesPerRiff[mrand()%9])
end
# determine how many riffs for this chord
#
riff nextRiffs(cur)
return(riffsPerBasis[triangle(0,9)])
end
LOSTRINGS = 4
STRINGS = 5
EGRAND = 8
int newport
int newsustain
int newpatch
int disturbFlag = FALSE
int resttime
int restflag = FALSE
riff disturbMelodySetup()
int rno
disturbFlag = TRUE
# must force a time switch, rest at end of chord
# change doesn't hurt either. time switch needed
# for 2nd voice to imitate
resttime = mchoose(q,e,q+e)
restflag = TRUE
rest resttime
rno = mchoose(0,1)
if (rno)
newpatch = mchoose(LOSTRINGS,STRINGS,EGRAND)
if (newpatch == LOSTRINGS)
octave = 12
else
octave = 0
end
patch newpatch
newport = mchoose(0,0,0,0,5,10,10,15)
ccont 0 PORTAMENTO newport
newsustain = mchoose(0,127)
ccont 0 SUSTAINPEDAL newsustain
if (debug)
void printf("newpatch %d\n",newpatch)
void printf("newport %d\n",newport)
void printf("newsustain %d\n",newsustain)
end
end
end
riff disturbDoppelGanger()
rest resttime
disturbFlag = FALSE
patch newpatch
ccont 0 PORTAMENTO newport
ccont 0 SUSTAINPEDAL newsustain
end
int rno
int nnote
int ntime
int nvel
riff playIt(nn,nt,nv)
rno = mchoose(0,1,2,3)
nnote = nn+octave
ntime = nt
nvel = nv
if ( rno == 0 )
nnote nt nv
else if ( rno == 1 )
nnote-12 0,nt nv
nnote nt nv
else if ( rno == 2 )
nnote-12 0,nt nv
nnote-5 0,nt nv
nnote nt nv
else if ( rno == 3 )
nnote nt nv
end
end
riff imitate()
if ( rno == 0 )
nnote ntime nvel
else if ( rno == 1 )
nnote-12 0,ntime nvel
nnote ntime nvel
else if ( rno == 2 )
nnote-12 0,ntime nvel
nnote-5 0,ntime nvel
nnote ntime nvel
else if ( rno == 3 )
nnote ntime nvel
end
end
# @include pan1.ma
riff vco1sect1()
end
riff vco2sect1()
end
riff vco3sect1()
end
riff vco4sect1()
end
# melody
#
vco melody
int curbasis # current chord in progression
int curnotes # number of notes in riff
int curriffs # riffs per chord
int cr # current riff index
int cn # current note index
int rno # random number variable
int scalemode # major or minor mode index
int newnote
int newtime
int newvel
# pass per ccont pan time in from mos argv
# environment pointer
#
panvalue = atoi(&argv)
if (panvalue == 0)
panvalue = 5
end
void printf("panvalue = %d\n",panvalue)
void vco1sect1()
# section two
# section three
scalemode = mrand() % 2
for( curbasis = 0; ; )
curriffs = nextRiffs(0)
#
# for some number of riffs
for( cr = 0; cr < curriffs; cr++)
# for each riff play some number of notes
#
curnotes = nextNotes(0)
newvel = mrandrange(90,100)
for( cn = 0; cn < curnotes; cn++)
rno = mfractal1(rno) % 7
if (scalemode)
newnote = basis[curbasis] + major[rno]
else
newnote = basis[curbasis] + minor[rno]
end
newvel = newvel + 5
if ( newvel > 120 )
newvel = 89
end
newtime = mchoose(q,e,s,s,s,s,s,s,e,e,e,e,q+e)
# void printf("%d %d %d\n",newnote,newtime,newvel)
void playIt(newnote,newtime,newvel)
newnote newtime newvel
end
# sometimes throw in a rest
#
rno = mrand() % 3
if (rno)
resttime = mchoose(q,e,e,h+q,e,q+e)
rest resttime
restflag = TRUE
end
end
curbasis = nextBasis(curbasis)
# flip coin to decide if major/minor mode
#
scalemode = mrand() % 2
void disturbMelodySetup()
end
end
vco melodyDup
void vco2sect1()
# section three
for(;;)
#void printf("v2 restflag %d\n",restflag)
if (restflag)
restflag = FALSE
rest resttime
else
void imitate()
end
if (disturbFlag)
void disturbDoppelGanger()
end
end
end
vco pan1
int decflag
int mcount
int vol
int dirflag
void vco3sect1()
# force pan control to left channel, mixer must be setup to
# match
vol1 = PANLEFT
vol2 = PANRIGHT
for(;;)
if (vol1 >= PANLEFT)
void printf("PAN LEFT max %d %d\n",vol1,vol2)
decflag = TRUE
else if (vol1 <= PANRIGHT)
void printf("PAN LEFT min %d %d\n",vol1,vol2)
decflag = FALSE
end
if (decflag)
vol1--
vol2++
else
vol1++
vol2--
end
ccont panvalue VOLUME vol1
#void printf("vol1 %d ",vol1)
end
end
vco pan2
int mcount
int vol
int dirflag
void vco4sect1()
# force pan control to right channel, mixer must be setup to
# match
for(;;)
ccont panvalue VOLUME vol2
#void printf("vol2 %d\n",vol2)
end
end